<template>
  <lay-card>
    <lay-layer
      v-model="visibleSqlData"
      :title="'预览生成的测试数据'"
      :shade="false" :area="['80%', '70%']"
    >
        <ReviewData
            :executeId="execute_id"
            @insertData="insertData"
        ></ReviewData>
    </lay-layer>
    <lay-form :model="sceneForm" :rules="rules" required>
      <lay-row space="10">
<!--        <lay-col md="6"><span class="title-left">数据库：</span></lay-col>-->
        <lay-col md="24">
          <lay-form-item label="数据库" prop="database">
            <lay-tree-select
              size="sm"
              v-model="sceneForm.connect_url_id"
              :data="dataSources" multiple
              style="width: 90%"
            ></lay-tree-select>
          </lay-form-item>
        </lay-col>
      </lay-row>
      <lay-row space="10">
<!--        <lay-col md="6"><span class="title-left">数据量：</span></lay-col>-->
        <lay-col md="16">
          <lay-form-item label="数据量" prop="dataNumber">
            <lay-input-number
              size="sm"
              v-model="sceneForm.number"
              :min="1"
              :max="100"
              style="width: 100%"
            ></lay-input-number>
          </lay-form-item>
        </lay-col>
        <lay-col md="8">
          <span style="margin-left: 5px;margin-bottom: 10px">组(限制在1-100组内)</span>
        </lay-col>
      </lay-row>
      <lay-row space="10">
        <lay-col md="10">
          <lay-form-item label="是否预览" prop="isViewData">
            <lay-switch size="sm" v-model="sceneForm.insertFlag" style="width: 200px"></lay-switch>
          </lay-form-item>
        </lay-col>
      </lay-row>
      <lay-row space="10">
        <lay-col md="22">
          <lay-form-item style="text-align: center;">
            <lay-button size="sm" @click="cancelProduct" style="margin-right: 20px">取消</lay-button>
            <lay-button :disabled="btn_disable" size="sm" type="normal" @click="productData">确定</lay-button>
          </lay-form-item>
        </lay-col>
      </lay-row>
      <lay-row space="20">
        <lay-col md="3"><div style="margin-top: 0;margin-left: 10px;color: blue">生成：</div></lay-col>
        <lay-col md="21">
          <lay-progress
              style="margin-top: 15px"
              :percent="percent"
              :show-text="true"
          ></lay-progress>
        </lay-col>
      </lay-row>
      <lay-row space="20">
        <lay-col md="3"><div style="margin-top: 0;margin-left: 10px;color: blue">插入：</div></lay-col>
        <lay-col md="21">
          <lay-progress
              style="margin-top: 15px"
              :percent="percentInsert"
              theme="green"
              :show-text="true"
              :text="InsertResult"
          ></lay-progress>
        </lay-col>
      </lay-row>
    </lay-form>
  </lay-card>
</template>

<script lang="ts">
import ReviewData from "./ReviewData.vue";
import {viewSql} from "../../../store/databases/CommonFunction";

export default {
  name: "ProductData",
  components: {
    ReviewData
  }
}
</script>

<script lang="ts" setup>

import {onBeforeMount, onUnmounted, reactive, ref} from "vue";
import {executeSceneApi, insertDataApi, queryInsertSqlProgress, queryProgress} from "../../../api/module/scene";
import {getAllLinksTress} from "../../../api/module/db";
import {layer} from "@layui/layui-vue";
import {notify} from "../../../untils/tip";
import {viewSql} from "../../../store/databases/CommonFunction";

const rules = ref({
  number : {
    type: Number,
    min: 1,
    max: 100
  }
})

const sceneForm = reactive({number: 2, insertFlag: true, connect_url_id: [], scene_id: '', scene_name: ''})
const dataSources = ref([]);

const visibleSqlData = ref(false);

const percent = ref(0);           // 数据生成进度
const percentInsert = ref(0);     // 数据插入进度
const InsertResult = ref("0/0/0");     // 数据插入进度

const timer = ref();
const execute_id = ref(null);
const btn_disable = ref(false);

const {scene_info, cancelAction} = defineProps({
  scene_info: {type: Object, default: reactive({scene_id: '',scene_name: ''})},
  cancelAction: {type: Function}
});

onBeforeMount(() => {
  sceneForm.scene_id = scene_info.scene_id;
  sceneForm.scene_name = scene_info?.scene_name;
  console.log(sceneForm);
  getTreeDBS();
})

const getTreeDBS = async () => {
  let {result, status, message} = await getAllLinksTress();
  if (status === 'success'){
      dataSources.value = result.children;
  }else {
    layer.msg(message);
  }
};

const loading = function() {
    layer.load(0, {time: (100-percent.value)*1000})
}

/** 获取数据生成的进度 **/
const getPercent = async (res: any) => {
  let {result, status, message} = await queryProgress({execute_id: res.execute_id});
  if(status === 'success'){
    percent.value = result.progress;
    if(result.execute_status === 'SUCCESS' && result.progress === 100){
      clearInterval(timer.value);
      timer.value = '';
      btn_disable.value = false;
      if(sceneForm.insertFlag){
        visibleSqlData.value = true;
      }else {
        notify('success', '数据插入中...')
        await insertData();
      }
    }
    else if(result.execute_status === 'FAILED') {
      clearInterval(timer.value);
      timer.value = '';
      btn_disable.value = false;
      notify(result.execute_status, message);
    }
  }
};

/**插入数据**/
const timerInsert = ref();

/** 查询数据插入的进度 **/
const queryInsertSQLPercent = async (execute_id: number) => {
  let {result, status, message} = await queryInsertSqlProgress({execute_id: execute_id});
  if(status === 'success'){
    if(result.insert_status === 'WAIT'){
      percentInsert.value = (result.success + result.failed) / result.total * 100;
      InsertResult.value = String(result.success) + "/" + result.failed + "/" + result.total;
    } else if(result.insert_status === 'SUCCESS') {
      percentInsert.value = (result.success + result.failed) / result.total * 100;
      InsertResult.value = String(result.success) + "/" + result.failed + "/" + result.total;
      clearInterval(timerInsert.value);
      timerInsert.value = '';
      btn_disable.value = false;
      notify("success", "插入完成，[成功/失败/总数]的结果如下：" + InsertResult.value);
      viewSql({id: execute_id});
    } else if(result.insert_status === 'FAILED') {
      clearInterval(timerInsert.value);
      timerInsert.value = '';
      btn_disable.value = false;
      notify("failed", message);
      viewSql({id: execute_id});
    }else {
        notify("failed", "未知状态！");
    }
  }else {
    clearInterval(timerInsert.value);
    timerInsert.value = '';
    btn_disable.value = false;
    notify("failed", "查询插入进度的接口请求失败！");
  }
}

const insertData = async () => {
  visibleSqlData.value = false;
  const params = reactive({execute_id: execute_id.value, connect_url_id: sceneForm.connect_url_id})
  let {result, status, message} = await insertDataApi(params);
  if(status === 'success'){
    let countInsert = 0;
    timerInsert.value = setInterval(()=>{
      queryInsertSQLPercent(params.execute_id);
      countInsert ++;
      if(countInsert > 3600){
        clearInterval(timerInsert.value);
        notify("failed", "超时退出！")
      }
    }, 500)
  }else {
    notify(status, message);
  }
};

const cancelProduct = () => {
  cancelAction();
}

const productData = async () => {
  if(sceneForm.connect_url_id.length > 0){
      percent.value = 0;
      percentInsert.value = 0;
      InsertResult.value = '0/0/0';
      btn_disable.value = true;
      console.log('product sceneForm:', sceneForm)
      localStorage.setItem('createSceneForm', JSON.stringify(sceneForm))
      let {result, status, message} = await executeSceneApi(sceneForm);
      if(status === 'success'){
        execute_id.value = result.execute_id;
        let countProduct = 0;
        timer.value = setInterval(()=>{
          getPercent(result);
          countProduct ++;
          if(countProduct > 5400){
            clearInterval(timer.value);
            notify("failed", "超时退出！")
          }
        }, 500)
      }else {
        // layer.msg(message);
        notify("failed", message)
      }
  } else {
      notify("failed", "未选择待插入的库！")
  }

};

// 销毁前清理定时任务
onUnmounted(() => {
  if(timer.value){clearInterval(timer.value);}
  timer.value = '';
  if(timerInsert.value){clearInterval(timerInsert.value);}
  timerInsert.value = ''
})

</script>

<style scoped>
.title-left {
  margin-top: 5px;
  margin-right: 10px;
  float: right;
}
</style>